The Other Windows

There are four other windows the skin still needs: Event list, Todo list, Alarm and the Tooltip. We could also define the tray icon but since it requires images we'll settle for the build-in icon.

For event list we'll create a new window, set the background for it and define the actual list item.

<window id="Event List" w="200" threshold="48" default="1">
  <image id="Event List.background1" element="gradient.background1" origin1="TOP-LEFT" x1="0" y1="0" origin2="BOTTOM-RIGHT" x2="0" y2="0" color="249, 237, 204" minsizefromimage="0" />
  <image id="Event List.background2" element="gradient.background2" origin1="TOP-LEFT" x1="3" y1="35" origin2="BOTTOM-RIGHT" x2="-3" y2="-3" color="249, 237, 204" minsizefromimage="0" />
  <text id="Event List.header" element="font.large" x="5" y="5" align="TOP-LEFT" text="Event List" />
  <eventlist id="Event List.eventlist" origin1="TOP-LEFT" x1="10" y1="40" origin2="BOTTOM-RIGHT" x2="-10" y2="-10">
    <header>
      <appearance element="font.bold" color="249, 237,204" align="TOP-LEFT" />
    </header>
    <item>
      <appearance element="font.normal" color="102, 35, 36" align="TOP-LEFT" />
    </item>
    <separator id="Event List.separator" padding="0, 10, 0, 0" />
  </eventlist>
</window>

Couple of things you should note about the event list window: the window doesn't define any height and the background images and the event list do not define absolute size. This is because the window will automatically adjust its height from the contents of the list. The background images are defined so that it always fills the whole window from top left to bottom right. The minsizefromimage must be set to "0" for the images. This is because the gradient is really a 1x256 size image so unless we tell Rainlendar that it's ok to shrink the image it would set the minimum size of the window to 256 which wouldn't look too good.

The text element just draw the header to the window. The text gets automatically translated too if it can be found from the translated strings.

The actual event list's position is defined the same way as the background but with some additional padding in the edges. Event list contains header and item which define the appearance for the texts. The separator is used to add some space between the items (it could also draw e.g. an image between the items).

The todo list is very similar as the event list. In fact the only difference is the id attributes and that we'll create a <todolist> instead of <eventlist>.

<window id="Todo List" w="200" threshold="48" default="1">
  <image id="Todo List.background1" element="gradient.background1" origin1="TOP-LEFT" x1="0" y1="0" origin2="BOTTOM-RIGHT" x2="0" y2="0" color="249, 237, 204" minsizefromimage="0" />
  <image id="Todo List.background2" element="gradient.background2" origin1="TOP-LEFT" x1="3" y1="35" origin2="BOTTOM-RIGHT" x2="-3" y2="-3" color="249, 237, 204" minsizefromimage="0" />
  <text id="Todo List.header" element="font.large" x="5" y="5" align="TOP-LEFT" text="Todo List" />
  <todolist id="Todo List.todolist" origin1="TOP-LEFT" x1="10" y1="40" origin2="BOTTOM-RIGHT" x2="-10" y2="-10">
    <header>
      <appearance element="font.bold" color="249, 237, 204" align="TOP-LEFT" />
    </header>
    <item>
      <appearance element="font.normal" color="102, 35, 36" align="TOP-LEFT" />
    </item>
    <separator id="Todo List.separator" padding="0, 10, 0, 0" />
  </todolist>
</window>

The alarm window isn't much different than the rest.

<alarm id="Alarm" threshold="48" textmargins="10, 40, 10, 10">
  <image id="Alarm.background1" element="gradient.background1" origin1="TOP-LEFT" x1="0" y1="0" origin2="BOTTOM-RIGHT" x2="0" y2="0" color="249, 237, 204" minsizefromimage="0" />
  <image id="Alarm.background2" element="gradient.background2" origin1="TOP-LEFT" x1="3" y1="35" origin2="BOTTOM-RIGHT" x2="-3" y2="-3" color="249, 237, 204" minsizefromimage="0" />
  <text id="Alarm.header" element="font.large" x="5" y="5" align="TOP-LEFT" text="Rainlendar" />
  <item id="Alarm.item">
    <appearance element="font.normal" color="102, 35, 36" align="TOP-LEFT" />
  </item>
  <button id="Alarm.button.dismissall" origin1="TOP-LEFT" x1="0" y1="0" origin2="BOTTOM-RIGHT" x2="0" y2="0" action="Global_DismissAll()" />
</alarm>

Note that the alarm is not a <window> but uses a <alarm> tag instead. You never define the size of the alarm as it is calculated automatically. The textmargins define the area around the alarm window which is added as margins for the text. The alarm window can contain all the same items as a normal window but in addition to that it also defines the list's <item> element which contains the appearance for the alarm items.

In the alarm we also define a transparent button (it's transparent because we don't define any graphical element for it) which covers the whole window.  Pressing the button will dismiss all alarms that the window contains. The Global_DismissAll() is the name of the script that is executed when the button is pressed. You can check the Rainlendar's scripts folder for additional scripts that can be executed. In the alarm window you might want to have also a button which snoozes the alarms.

The last window we'll have to define is the tooltip.

<tooltip id="Tooltip" threshold="48" textmargins="10, 10, 10, 10" offset="0, 0">
  <image id="Tooltip.background1" element="gradient.background1" origin1="TOP-LEFT" x1="0" y1="0" origin2="BOTTOM-RIGHT" x2="0" y2="0" color="249, 237, 204" minsizefromimage="0" />
  <image id="Tooltip.background2" element="gradient.background2" origin1="TOP-LEFT" x1="3" y1="3" origin2="BOTTOM-RIGHT" x2="-3" y2="-3" color="249, 237, 204" minsizefromimage="0" />
  <header>
    <appearance element="font.bold" color="102, 35, 36" align="TOP-LEFT" />
  </header>
  <item>
    <appearance element="font.normal" color="102, 35, 36" align="TOP-LEFT" />
  </item>
  <separator id="Tooltip.separator" padding="0, 10, 0, 0" />
</tooltip>

That's pretty much the same as the alarm window. The tooltip has a special element just like the alarm and it also defines the text margins. The offset defines how far the window is opened from the mouse pointer. This is useful if the tooltip has e.g. an arrow which should  be under the mouse. In our example the tooltip is just a rectangle so we don't define any offset.

The rest is pretty much a copy from the alarm window with the exception that the tooltip doesn't have any title (it could though...).

Prev - Next


The finished skin.xml should be like this now:

<?xml version="1.0" encoding="UTF-8"?>
<skin version="1.0">
  <info>
    <version>1.0</version>
    <author>Rainy</author>
    <email>rainy@iki.fi</email>
    <homepage>http://www.rainlendar.net</homepage>
    <comment>The result of the skinning tutorial.</comment>
  </info>

  <elements>
    <font id="font.normal" facename="Arial" size="12" />
    <font id="font.bold" facename="Arial" weight="BOLD" size="12" />
    <font id="font.large" facename="Arial" weight="BOLD" size="14" />
    <font id="font.small" facename="Arial" size="6" />
    <gradient id="gradient.background1" color1="201, 131, 59" color2="237, 170, 100" direction="VERTICAL" />
    <gradient id="gradient.background2" color1="237, 170, 100" color2="201, 131, 59" direction="VERTICAL" />
  </elements>

  <window id="Calendar" w="200" h="200" threshold="48" default="1">
    <image id="Calendar.background1" element="gradient.background1" x="0" y="0" w="200" h="200" />
    <image id="Calendar.background2" element="gradient.background2" x="3" y="43" w="194" h="154" />
    <month id="Calendar.month" element="font.large" x="5" y="5" align="TOP-LEFT" />
    <year id="Calendar.year" element="font.large" x="195" y="5" align="TOP-RIGHT" />
    <calendar id="Calendar.calendar" x="5" y="25" w="190" h="170" layout="GRID">
      <weekdays abbreviate="1">
        <appearance element="font.small" color="249, 237, 204" align="CENTER" />
      </weekdays>
      <days>
        <appearance layer="0" priority="0" element="font.normal" color="102, 35, 36" align="CENTER" />
      </days>
      <today>
        <appearance layer="0" priority="100" element="font.bold" color="249, 237, 204" align="CENTER" />
      </today>
      <events>
        <appearance layer="0" priority="1" element="font.bold" color="102, 35, 36" align="CENTER" />
      </events>
    </calendar>
  </window>

  <window id="Event List" w="200" threshold="48" default="1">
    <image id="Event List.background1" element="gradient.background1" origin1="TOP-LEFT" x1="0" y1="0" origin2="BOTTOM-RIGHT" x2="0" y2="0" color="249, 237, 204" minsizefromimage="0" />
    <image id="Event List.background2" element="gradient.background2" origin1="TOP-LEFT" x1="3" y1="35" origin2="BOTTOM-RIGHT" x2="-3" y2="-3" color="249, 237, 204" minsizefromimage="0" />
    <text id="Event List.header" element="font.large" x="5" y="5" align="TOP-LEFT" text="Event List" />
    <eventlist id="Event List.eventlist" origin1="TOP-LEFT" x1="10" y1="40" origin2="BOTTOM-RIGHT" x2="-10" y2="-10">
      <header>
        <appearance element="font.bold" color="249, 237,204" align="TOP-LEFT" />
      </header>
      <item>
        <appearance element="font.normal" color="102, 35, 36" align="TOP-LEFT" />
      </item>
      <separator id="Event List.separator" padding="0, 10, 0, 0" />
    </eventlist>
  </window>

  <window id="Todo List" w="200" threshold="48" default="1">
    <image id="Todo List.background1" element="gradient.background1" origin1="TOP-LEFT" x1="0" y1="0" origin2="BOTTOM-RIGHT" x2="0" y2="0" color="249, 237, 204" minsizefromimage="0" />
    <image id="Todo List.background2" element="gradient.background2" origin1="TOP-LEFT" x1="3" y1="35" origin2="BOTTOM-RIGHT" x2="-3" y2="-3" color="249, 237, 204" minsizefromimage="0" />
    <text id="Todo List.header" element="font.large" x="5" y="5" align="TOP-LEFT" text="Todo List" />
    <todolist id="Todo List.todolist" origin1="TOP-LEFT" x1="10" y1="40" origin2="BOTTOM-RIGHT" x2="-10" y2="-10">
      <header>
        <appearance element="font.bold" color="249, 237, 204" align="TOP-LEFT" />
      </header>
      <item>
        <appearance element="font.normal" color="102, 35, 36" align="TOP-LEFT" />
      </item>
      <separator id="Todo List.separator" padding="0, 10, 0, 0" />
    </todolist>
  </window>

  <tooltip id="Tooltip" threshold="48" textmargins="10, 10, 10, 10" offset="0, 0">
    <image id="Tooltip.background1" element="gradient.background1" origin1="TOP-LEFT" x1="0" y1="0" origin2="BOTTOM-RIGHT" x2="0" y2="0" color="249, 237, 204" minsizefromimage="0" />
    <image id="Tooltip.background2" element="gradient.background2" origin1="TOP-LEFT" x1="3" y1="3" origin2="BOTTOM-RIGHT" x2="-3" y2="-3" color="249, 237, 204" minsizefromimage="0" />
    <header>
      <appearance element="font.bold" color="102, 35, 36" align="TOP-LEFT" />
    </header>
    <item>
      <appearance element="font.normal" color="102, 35, 36" align="TOP-LEFT" />
    </item>
    <separator id="Tooltip.separator" padding="0, 10, 0, 0" />
  </tooltip>

  <alarm id="Alarm" threshold="48" textmargins="10, 40, 10, 10">
    <image id="Alarm.background1" element="gradient.background1" origin1="TOP-LEFT" x1="0" y1="0" origin2="BOTTOM-RIGHT" x2="0" y2="0" color="249, 237, 204" minsizefromimage="0" />
    <image id="Alarm.background2" element="gradient.background2" origin1="TOP-LEFT" x1="3" y1="3" origin2="BOTTOM-RIGHT" x2="-3" y2="-3" color="249, 237, 204" minsizefromimage="0" />
    <text id="Alarm.header" element="font.large" x="5" y="5" align="TOP-LEFT" text="Rainlendar" />
    <item id="Alarm.item">
      <appearance element="font.normal" color="102, 35, 36" align="TOP-LEFT" />
    </item>
    <button id="Alarm.button.dismissall" origin1="TOP-LEFT" x1="0" y1="0" origin2="BOTTOM-RIGHT" x2="0" y2="0" action="Global_DismissAll()" />
  </alarm>

</skin>